package cn.net.cfss.fgbp.provider.console.biz;

import cn.net.cfss.fgbp.api.console.constant.DeleteFlagEnum;
import cn.net.cfss.fgbp.api.console.constant.MenuTypeEnum;
import cn.net.cfss.fgbp.api.console.dto.SysMenuDto;
import cn.net.cfss.fgbp.api.console.dto.SysRoleDto;
import cn.net.cfss.fgbp.api.console.dto.SysRoleProjectDto;
import cn.net.cfss.fgbp.api.console.dto.SysUserRoleDto;
import cn.net.cfss.fgbp.api.console.vo.SysMenuVo;
import cn.net.cfss.fgbp.base.common.biz.BaseBiz;
import cn.net.cfss.fgbp.provider.console.dao.SysMenuDtoMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author oygq
 * @title: MenuDtoBiz
 * @description: TODO
 * @date 2019/4/2 11:43
 */

@Service
public class SysMenuDtoBiz extends BaseBiz<SysMenuDtoMapper, SysMenuDto> {

    @Autowired
    SysUserRoleDtoBiz sysUserRoleDtoBiz;

    @Autowired
    SysRoleDtoBiz sysRoleDtoBiz;

    @Autowired
    SysRoleProjectDtoBiz sysRoleProjectDtoBiz;

    /**
     * 菜单树查询
     *
     * @param vo
     * @param isMenu true菜单树，false菜单按钮树
     * @return
     */
    public List<SysMenuDto> tree(SysMenuVo vo, boolean isMenu) {
        //查询所有的菜单，通过Java逻辑分类
        if (null == vo) {
            vo = new SysMenuVo();
        }
        vo.setDeleteFlag(DeleteFlagEnum.NOT_DEL);
        //根据用户id查询用户的角色信息
        if (null != vo.getUserId()){
            //查询用户的角色
            SysUserRoleDto userRoleDto = new SysUserRoleDto();
            userRoleDto.setUserId(vo.getUserId());
            List<SysUserRoleDto> roleList = sysUserRoleDtoBiz.selectList(userRoleDto);
            List<Long> roles = new ArrayList<>();
            for (SysUserRoleDto dto : roleList) {
                SysRoleDto roleDto = new SysRoleDto();
                roleDto.setDeleteFlag(DeleteFlagEnum.NOT_DEL);
                roleDto.setId(dto.getRoleId());
                roleDto = sysRoleDtoBiz.selectOne(roleDto);
                //超级管理员可以看所有
                if (null != roleDto && "super_admin".equals(roleDto.getRoleCode())){
                    break;
                }
                roles.add(dto.getRoleId());
            }
            vo.setRoleIds(roles);
        }
        //菜单树
        if (isMenu) {
            vo.setMenuType(MenuTypeEnum.MENU);
        }

        List<SysMenuDto> allMenu = mapper.queryList(vo);
        //找到最高层菜单
        return getMenu(allMenu);
    }


    public List<SysMenuDto> getMenu(List<SysMenuDto> allMenu){
        //找到最高层菜单
        List<SysMenuDto> menuList = new ArrayList<>();
        for (SysMenuDto menu : allMenu) {
            if (null == menu.getParentId() || 0 == menu.getParentId()) {
                menuList.add(menu);
            }
        }
        menuList.sort((x, y) -> x.getSort() - y.getSort());
        //递归获取子菜单
        for (SysMenuDto menu : menuList) {
            menu.setChild(getChild(menu.getId(), allMenu));
        }
        return menuList;
    }

    /**
     * 递归获取子菜单
     *
     * @param id
     * @param allMenu
     * @return
     */
    private List<SysMenuDto> getChild(Long id, List<SysMenuDto> allMenu) {
        List<SysMenuDto> childList = new ArrayList<>();
        //获取直接子菜单
        for (SysMenuDto menu : allMenu) {
            if (String.valueOf(id).equals(String.valueOf(menu.getParentId()))) {
                childList.add(menu);
            }
        }
        for (SysMenuDto menu : childList) {
            menu.setChild(getChild(menu.getId(), allMenu));
        }
        return childList;
    }

    public List<SysMenuDto> queryList(SysMenuVo vo) {
        return mapper.queryList(vo);
    }

    public void deleteBatch(List<Long> menuIds) {
        for (Long menuId : menuIds) {
            SysMenuVo menu = new SysMenuVo();
            menu.setId(menuId);
            menu.setUpdateTime(new Date());
            menu.setDeleteFlag(DeleteFlagEnum.DEL);
            updateSelectiveById(menu);
        }
    }

    public Map<Long, List<String>> selectMenuByRoleId(List<Long> roles) {
        Map<Long, List<String>> map = new HashMap<Long, List<String>>();
        List<String> list = new ArrayList<String>();
        //角色id不传就查所有
        if (roles == null || roles.size() == 0) {
            //获取所有有菜单的角色id
            roles = mapper.selectRolesAll();
            for (Long role : roles) {
                list = mapper.queryMenuByRoleId(role);
                if (list != null && list.size() > 0) {
                    //判断size为1 的空集合
                    if(list.size() == 1 && null == list.get(0) || list.size() == 0){
                        list = new ArrayList<>();
                    }
                    map.put(role, list);
                }

            }
            return map;
        }
        for (Long role : roles) {
            list = mapper.queryMenuByRoleId(role);
            if (list != null && list.size() > 0) {
                if(list.size() == 1 && null == list.get(0) || list.size() == 0){
                    list = new ArrayList<>();
                }
                map.put(role, list);
            }

        }
        return map;
    }

    public boolean check(String permission, Long id) {
        if (id != null) {
            SysMenuDto dto = selectById(id);
            if (permission.equals(dto.getPermission())) {
                return true;
            }
        }
        if (mapper.check(permission) > 0) {
            return false;
        }
        return true;
    }

    /**
     * 根据角色查询项目id，若角色id未传，查所有
     * @param roles
     * @return
     */
    public Map<Long, List<String>> queryProjectByRoleId(List<Long> roles) {
        Map<Long, List<String>> map = new HashMap<>();
        if (roles != null && roles.size() > 0) {
            for (Long role : roles){
                if (null == role){
                    continue;
                }
                List<SysRoleProjectDto> projectDtos = sysRoleProjectDtoBiz.queryByRoleIds(role);
                map.put(role, this.distinctProj(projectDtos));
            }
        }else{
            SysRoleDto roleDto = new SysRoleDto();
            roleDto.setDeleteFlag(DeleteFlagEnum.NOT_DEL);
            List<SysRoleDto> roleDtoList = sysRoleDtoBiz.selectList(roleDto);
            if (roleDtoList != null && roleDtoList.size() > 0){
                for (SysRoleDto dto : roleDtoList){
                    List<SysRoleProjectDto> projectDtos = sysRoleProjectDtoBiz.queryByRoleIds(dto.getId());
                    map.put(dto.getId(), this.distinctProj(projectDtos));
                }
            }
        }
        return map;
    }

    public List<String> distinctProj(List<SysRoleProjectDto> projectDtos){
        List<String> list = new ArrayList<>();
        if (null != projectDtos && projectDtos.size() > 0){
            list = projectDtos.stream().map(proj -> proj.getProjPkId()).filter(projId -> StringUtils.isNotBlank(projId)).distinct().collect(Collectors.toList());
        }
        return list;
    }

    public void updateSortNullById(Long id) {
        mapper.updateSortNullById(id);
    }
}
